package game.ball;

import game.soccerField.SoccerField;

import com.uqbar.vainilla.DeltaState;

public abstract class SoccerBallState {
	
	private double versorI   = 0;
	private double versorJ   = 0;
	private double speed     = 0;
	private int acceleration = 0;
	private SoccerBall ball;

	public abstract void update(DeltaState deltaState);
	
	public void move(SoccerField field, double x, double y) {
		if (this.isWithinTheField(field))
			this.getBall().getScene().moveSprites(x, y);
		else {
			if (this.isInNorthEnd(field)) {
				if (y >= 0) {
					this.moveUpDownWithCentralizedCamera(x, y);
				}
				else {
					this.advance(x, y);
				}
			}
			else {
				if (this.isInSouthEnd(field)) {
					if (y <= 0) {
						this.moveUpDownWithCentralizedCamera(x, y);
					}
					else {
						this.advance(x, y);
					}
				}
				else {
					if (this.isInEastEnd(field)) {
						if (x >= 0) {
							this.moveRightLeftWithCentralizedCamera(x, y);
						}
						else {
							this.advance(x, y);
						}
					}
					else {
						if (this.isInWestEnd(field)) {
							if (x <= 0) {
								this.moveRightLeftWithCentralizedCamera(x, y);
							}
							else {
								this.advance(x, y);
							}
						}						
					}
				}
			}			
		}
	}

	protected abstract void advance(double x, double y);

	protected abstract void moveRightLeftWithCentralizedCamera(double x, double y);

	protected abstract void moveUpDownWithCentralizedCamera(double x, double y);
	
	protected boolean isInNorthEnd(SoccerField field) {
		return this.getBall().getY() < field.getY() + SoccerField.LIMIT_UP;
	}
	
	protected boolean isInSouthEnd(SoccerField field) {
		return this.getBall().getY() + this.getBall().getAppearance().getHeight() > field.getY() + field.getAppearance().getHeight() - SoccerField.LIMIT_DOWN; 
	}
	
	protected boolean isInEastEnd(SoccerField field) {
		return this.getBall().getX() < field.getX() + SoccerField.LIMIT_LEFT;
	}
	
	protected boolean isInWestEnd(SoccerField field) {
		return this.getBall().getX() + this.getBall().getAppearance().getWidth() > field.getX() + field.getAppearance().getWidth() - SoccerField.LIMIT_RIGHT;
	}

	protected boolean isWithinTheField(SoccerField field) {
		return this.getBall().getX() >= field.getX() + SoccerField.LIMIT_LEFT &&
				this.getBall().getX() + this.getBall().getAppearance().getWidth() <= field.getX() + field.getAppearance().getWidth() - SoccerField.LIMIT_RIGHT &&
				this.getBall().getY() >= field.getY() + SoccerField.LIMIT_UP &&
				this.getBall().getY() + this.getBall().getAppearance().getHeight() <= field.getY() + field.getAppearance().getHeight() - SoccerField.LIMIT_DOWN;
	}
	
	
	

	public void setVersorI(double i) {
		this.versorI = i;
	}

	public void setVersorJ(double j) {
		this.versorJ = j;
	}

	public void setSpeed(double speed) {
		this.speed = speed;
	}

	public double getVersorI() {
		return versorI;
	}

	public double getVersorJ() {
		return versorJ;
	}

	public int getAcceleration() {
		return acceleration;
	}

	public double getSpeed() {
		return speed;
	}

	public SoccerBall getBall() {
		return ball;
	}

	public void setBall(SoccerBall ball) {
		this.ball = ball;
	}

	public abstract boolean isFree();
}
